package com.zhijian.medical.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhijian.medical.dao.local.RoutineSingleSampleQpMapper;
import com.zhijian.medical.entity.dto.PersonDto;
import com.zhijian.medical.entity.po.RoutineSample;
import com.zhijian.medical.entity.po.RoutineSingleSample;
import com.zhijian.medical.entity.po.RoutineSingleSampleQp;
import com.zhijian.medical.entity.vo.request.RoutineSingleSampleQpSearchVo;
import com.zhijian.medical.entity.vo.request.RoutineSingleSampleSearchVo;
import com.zhijian.medical.entity.vo.response.RoutineSingleSampleVo;
import com.zhijian.medical.holder.CurrentUserHolder;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 样本切片功能
 */
@Service
public class RoutineSingleSampleQpService extends ServiceImpl<RoutineSingleSampleQpMapper, RoutineSingleSampleQp> implements IService<RoutineSingleSampleQp> {

    @Autowired
    CacheService cacheService;

    @Autowired
    RoutineSingleSampleService routineSingleSampleService;

    @Autowired
    RoutineSingleSampleQpMapper routineSingleSampleQpMapper;

    public List<RoutineSingleSampleQp> selectListByRsjCode(List<String> rsjCodeList){
        if (!CollectionUtils.isEmpty(rsjCodeList)){
            QueryWrapper<RoutineSingleSampleQp> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("rsj_code", rsjCodeList);
            RoutineSingleSampleQp param = new RoutineSingleSampleQp();
            param.setRsjCodeList(rsjCodeList);
            return routineSingleSampleQpMapper.readRsjInfo(param);
        }
        return new ArrayList<>(0);
    }

    public List<RoutineSingleSampleQp> selectList(RoutineSingleSampleQpSearchVo searchVo){
        List<RoutineSingleSampleQp> routineSingleSampleQpList = routineSingleSampleQpMapper.selectPageList(searchVo);
        for (RoutineSingleSampleQp routineSingleSampleQp : routineSingleSampleQpList){
            String[] numberArr = routineSingleSampleQp.getNumber().split("-");
            routineSingleSampleQp.setBlh(numberArr[0]);
        }
        return routineSingleSampleQpList;
    }

    /**
     * 生成切片
     * @param personDto 当前登陆人信息
     * @param moreNum 白片额外的切片数
     * @param qpTypeEnum 切片类型
     */
    public void generateQp(PersonDto personDto, Integer moreNum, QpTypeEnum qpTypeEnum){
        String sampleNum = readSampleNum(personDto, qpTypeEnum);
        if (StringUtils.hasText(sampleNum)){
            String[] sampleNumArr = sampleNum.split(",");
            addQp(Arrays.asList(sampleNumArr), moreNum, qpTypeEnum, 0);
        }
    }

    public void generateQp(PersonDto personDto, QpTypeEnum qpTypeEnum){
        String sampleNum = readSampleNum(personDto, qpTypeEnum);
        if (StringUtils.hasText(sampleNum)){
            String[] sampleNumArr = sampleNum.split(",");
            addQp(Arrays.asList(sampleNumArr), 1, qpTypeEnum, 0);
        }
    }

    /**
     * 各类型切片结束
     * @param personDto 当前登陆用户
     * @param qpTypeEnum 切片类型
     */
    public void endQp(PersonDto personDto, QpTypeEnum qpTypeEnum){
        String sampleNum = readSampleNum(personDto, qpTypeEnum);
        if (StringUtils.hasText(sampleNum)){
            String[] sampleNumArr = sampleNum.split(",");
            endQp(Arrays.asList(sampleNumArr));
        }
    }

    private String readSampleNum(PersonDto personDto, QpTypeEnum qpTypeEnum){
        String sampleNum;
        if(qpTypeEnum.equals(QpTypeEnum.HE)){
            sampleNum = cacheService.get("gl_qiepian:" + personDto.getId());
        }else {
            sampleNum = cacheService.get("gl_qiepian:"+qpTypeEnum.getCode()+":" + personDto.getId());
        }
        return sampleNum;
    }

    /**
     * 生成切片
     * @param singleSampleNumberList 样本列表
     * @param moreNum 切片数量
     * @param qpTypeEnum 切片类型
     */
    private void addQp(List<String> singleSampleNumberList, Integer moreNum, QpTypeEnum qpTypeEnum, Integer qpState){
        if (!CollectionUtils.isEmpty(singleSampleNumberList)){
            List<RoutineSingleSampleVo> routineSingleSampleList =
                    routineSingleSampleService.selectList(RoutineSingleSampleSearchVo.builder().numberList(singleSampleNumberList).build());
            List<RoutineSingleSampleQp> routineSingleSampleQpList = new LinkedList<>();
            List<Long> sampleIdList = routineSingleSampleList.stream().map(RoutineSingleSampleVo::getId).collect(Collectors.toList());
            deleteExtraQp(sampleIdList);
            Date now = new Date();
            for (RoutineSingleSampleVo routineSingleSampleVo : routineSingleSampleList){
                if (moreNum <= 1){
                    RoutineSingleSampleQp beanCopy = new RoutineSingleSampleQp();
                    BeanUtils.copyProperties(routineSingleSampleVo, beanCopy);
                    beanCopy.setCreateTime(now);
                    beanCopy.setUpdateTime(now);
                    beanCopy.setSampleId(routineSingleSampleVo.getId());
                    beanCopy.setId(null);
                    beanCopy.setQpType(qpTypeEnum.getCode());
                    beanCopy.setQpState(qpState);
                    routineSingleSampleQpList.add(beanCopy);
                }else {
                    for (int i = 1 ; i <= moreNum; i++){
                        RoutineSingleSampleQp beanCopy = new RoutineSingleSampleQp();
                        BeanUtils.copyProperties(routineSingleSampleVo, beanCopy);
                        beanCopy.setCreateTime(now);
                        beanCopy.setUpdateTime(now);
                        beanCopy.setSampleId(routineSingleSampleVo.getId());
                        beanCopy.setId(null);
                        beanCopy.setNumber(beanCopy.getNumber() + "-" + i);
                        beanCopy.setQpType(qpTypeEnum.getCode());
                        beanCopy.setQpState(qpState);
                        routineSingleSampleQpList.add(beanCopy);
                    }
                }
            }
            saveBatch(routineSingleSampleQpList);
        }
    }

    private void deleteExtraQp(List<Long> sampleIdList){
        if (!CollectionUtils.isEmpty(sampleIdList)){
            QueryWrapper<RoutineSingleSampleQp> delWrapper = new QueryWrapper<>();
            delWrapper.in("sample_id", sampleIdList);
            remove(delWrapper);
        }
    }

    private void endQp(List<String> singleSampleNumberList){
        if (!CollectionUtils.isEmpty(singleSampleNumberList)){
            List<RoutineSingleSampleVo> routineSingleSampleList =
                    routineSingleSampleService.selectList(RoutineSingleSampleSearchVo.builder().numberList(singleSampleNumberList).build());
            List<Long> sampleIdList = routineSingleSampleList.stream().map(RoutineSingleSampleVo::getId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(sampleIdList)) {
                QueryWrapper<RoutineSingleSampleQp> updWrapper = new QueryWrapper<>();
                updWrapper.in("sample_id", sampleIdList);
                RoutineSingleSampleQp updEntity = new RoutineSingleSampleQp();
                updEntity.setQpState(1);
                update(updEntity, updWrapper);
            }
        }
    }

    @Getter
    @AllArgsConstructor
    public enum QpTypeEnum{

        /**
         * HE切片
         */
        HE(0),
        /**
         * 白片
         */
        WHITE(1),

        /**
         * 细胞切片
         */
        CELL(2),

        /**
         * 特染切片
         */
        SS(3),
        /**
         * 细胞病理
         */
        XBBL(4),
        /**
         * 术中快速
         */
        SZKS(5);



        private Integer code;
    }

    @Getter
    @AllArgsConstructor
    public enum QpStateEnum{

        /**
         * 切片中
         */
        QP(0),
        /**
         * 已结束
         */
        QP_END(1);

        private Integer code;
    }
}
